package univer.oko.queryAnalizer.sqlEditor;

import javax.swing.text.AttributeSet;
import javax.swing.text.MutableAttributeSet;
import javax.swing.text.StyleConstants;
import java.awt.*;
import java.io.*;
import java.lang.reflect.Array;

/**
 * Created by Sergey Kharlamov.
 * Date: 22.07.2006
 * Time: 18:08:23
 */

public class EditorOptions implements Serializable {
    /**
     * Tekuschie nastrojki Zebry
     */
    protected static EditorOptions m_currentZebraOptions = null;
    /**
     * Predyduschaja kopija parametrov Zebry
     */
    protected static EditorOptions m_savedZebraOptions = null;

    //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    //  nastrojka razborschika kljuchevykh slov v mssql
    /**
     * podsvechivat' li STRING-constants
     */
    protected boolean[] TOKENIZER_CATEGORY_STRING_CONSTANTS;
    /**
     * podsvechivat' li NUMBER-constants
     */
    protected boolean[] TOKENIZER_CATEGORY_NUMBER_CONSTANTS;
    /**
     * podsvechivat' li comments
     */
    protected boolean[] TOKENIZER_CATEGORY_COMMENTS;
    /**
     * podsvechivat' li spec
     */
    protected boolean[] TOKENIZER_CATEGORY_SPEC;
    /**
     * podsvechivat' li IDENTIFIERs
     */
    protected boolean[] TOKENIZER_CATEGORY_IDENTIFIER;
    /**
     * podsvechivat' li proizvol'nyj nabor identifikatorov dlja kazhdoj iz kategorij
     */
    protected String[][] TOKENIZER_CATEGORY_IDENTIFIER_SET;
    /**
     * tekstovye stili sintaksicheskikh kategorij
     */
    protected MutableAttributeSet[] TOKENIZER_CATEGORY_STYLES;
    /**
     * obschee kolichestvo kategorij dlja mssql
     */
    protected int TOKENIZER_MSSQL_CATEGORY_COUNT;
    //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

    /**
     * Nachal'naja shirina rabochej oblasti Zebry.
     * Dlja vkljuchenija etoj anti-wrap fichi ustanovit' znachenie bol'she 1000.
     */
    protected int INITIAL_SCROLL_WIDTH;
    /**
     * Umolchatel'nyj tsvet fona paragrafa dokumenta Zebry
     */
    protected Color DEFAULT_PARAGRAPH_BCKG_COLOR;
    /**
     * Umolchatel'nyj tsvet teksta dokumenta Zebry
     */
    protected Color DEFAULT_TEXT_COLOR;
    /**
     * SHag podcherkivanija teksta
     */
    protected int DEFAULT_UNDERLINE_TEXT_STEP;
    /**
     * Umolchatel'nyj tsvet podcherkivanija ob'javlenija peremennykh
     */
    protected Color UNDERLINE_COLORS[];
    /**
     * Umolchatel'nyj stil' teksta dokumenta Zebry
     */
    protected MutableAttributeSet DEFAULT_TEXT_STYLE;

    /**
     * Umolchatel'nyj stil' teksta dokumenta Zebry
     */
    public MutableAttributeSet DEFAULT_PARAGRAPH_STYLE;

    /**
     * Pokazyvat' ili net nomera strok
     */
    protected boolean SHOW_LINE_NUMBERS;
    //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

    //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    /**
     * tekuschij prjamougol'nik okna soobschenij
     */
    protected Rectangle MESSAGES_WINDOW_RECT = null;
    /**
     * tekuschee rezhim pokaza okna soobschenij
     */
    protected boolean MESSAGES_ALWAYS_ON_TOP = false;
    //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

    static {
        // nachal'naja initsializatsija
        m_currentZebraOptions = new EditorOptions();
        m_currentZebraOptions.restoreDefaults();
    }

    /**
     * Vosstanavlivaet umolchatel'nye parametry Zebry
     */
    public void restoreDefaults() {
        TOKENIZER_CATEGORY_STRING_CONSTANTS = cloneArray(EditorConstants.TOKENIZER_CATEGORY_STRING_CONSTANTS);
        TOKENIZER_CATEGORY_NUMBER_CONSTANTS = cloneArray(EditorConstants.TOKENIZER_CATEGORY_NUMBER_CONSTANTS);
        TOKENIZER_CATEGORY_COMMENTS = cloneArray(EditorConstants.TOKENIZER_CATEGORY_COMMENTS);
        TOKENIZER_CATEGORY_SPEC = cloneArray(EditorConstants.TOKENIZER_CATEGORY_SPEC);
        TOKENIZER_CATEGORY_IDENTIFIER = cloneArray(EditorConstants.TOKENIZER_CATEGORY_IDENTIFIER);
        TOKENIZER_CATEGORY_IDENTIFIER_SET = (String[][]) cloneArray(EditorConstants.TOKENIZER_CATEGORY_IDENTIFIER_SET);
        TOKENIZER_CATEGORY_STYLES = (MutableAttributeSet[]) cloneArray(EditorConstants.TOKENIZER_CATEGORY_STYLES);
        TOKENIZER_MSSQL_CATEGORY_COUNT = TOKENIZER_CATEGORY_STRING_CONSTANTS.length;
        INITIAL_SCROLL_WIDTH = EditorConstants.INITIAL_SCROLL_WIDTH;
        DEFAULT_PARAGRAPH_BCKG_COLOR = EditorConstants.DEFAULT_PARAGRAPH_BCKG_COLOR;
        DEFAULT_TEXT_COLOR = EditorConstants.DEFAULT_TEXT_COLOR;
        DEFAULT_UNDERLINE_TEXT_STEP = EditorConstants.DEFAULT_UNDERLINE_TEXT_STEP;
        DEFAULT_PARAGRAPH_STYLE = EditorConstants.DEFAULT_PARAGRAPH_STYLE;
        DEFAULT_TEXT_STYLE = EditorConstants.DEFAULT_TEXT_STYLE;
        MESSAGES_WINDOW_RECT = null;
        MESSAGES_ALWAYS_ON_TOP = false;
    }

    /**
     * ustanavlivaet umolchatel'nye nastrojki dlja tekuschikh parametrov
     */
    public static void setCurrentDefaults() {
        if (m_currentZebraOptions == null) m_currentZebraOptions = new EditorOptions();
        m_currentZebraOptions.restoreDefaults();
    }


    /**
     * Zagruzhaet tekuschie nastrojki iz stroki
     */
    public static Object readSerialized(String src) {
        if (src == null)
            return null;
        ByteArrayInputStream bais = null;
        ObjectInputStream ois = null;
        Object obj = null;
        try {
            bais = new ByteArrayInputStream(src.getBytes());
            ois = new ObjectInputStream(bais);
            obj = ois.readObject();
        } catch (Throwable ex) {
        } finally {
            try {
                if (ois != null) {
                    ois.close();
                }
            } catch (Throwable ex) {
            }
        }
        return obj;
    }

    /**
     * Zagruzhaet tekuschie nastrojki iz stroki
     */
    public static String serializeToString(Object src) {
        ByteArrayOutputStream baos = null;
        ObjectOutputStream oos = null;
        String ret = null;
        try {
            baos = new ByteArrayOutputStream();
            oos = new ObjectOutputStream(baos);
            oos.writeObject(src);
            ret = new String(baos.toByteArray());
        } catch (Throwable ex) {
        } finally {
            try {
                if (oos != null) {
                    oos.close();
                }
            } catch (Throwable ex) {
            }
        }
        return ret;
    }

    /**
     * Sokhranjaet tekuschie nastrojki v umolchatel'nom fajle
     */
    public static void store() {
        store("D:\\EditorOptions.options");
    }

    /**
     * Zagruzhaet tekuschie nastrojki iz umolchatel'nogo fajla
     */
    public static void load() {
        load("D:\\EditorOptions.options");
    }

    /**
     * Sokhranjaet tekuschie nastrojki v fajle
     */
    public static void store(String fileName) {
        if (m_currentZebraOptions == null) return;
        FileOutputStream fos = null;
        ObjectOutputStream oos = null;
        try {
            fos = new FileOutputStream(fileName);
            oos = new ObjectOutputStream(fos);
            oos.writeObject(m_currentZebraOptions);
        } catch (Throwable ex) {
        }
        try {
            oos.close();
        } catch (Throwable ex) {
        }
        try {
            fos.close();
        } catch (Throwable ex) {
        }
    }

    /**
     * Zagruzhaet tekuschie nastrojki iz fajla
     */
    public static void load(String fileName) {
        File f = null;
        FileInputStream fis = null;
        ObjectInputStream ois = null;

        try {
            f = new File(fileName);
            if (f.exists()) {
                fis = new FileInputStream(f);
                ois = new ObjectInputStream(fis);
                m_currentZebraOptions = (EditorOptions) ois.readObject();
            }
        } catch (Throwable ex) {
            m_currentZebraOptions = new EditorOptions();
            m_currentZebraOptions.restoreDefaults();
        }
        try {
            ois.close();
        } catch (Throwable ex) {
        }
        try {
            fis.close();
        } catch (Throwable ex) {
        }
    }

    /**
     * chtenie boolean polja Zebry iz nastroek prilozhenija
     */
    protected boolean read(String key, boolean defaultValue) {
        Boolean obj = (Boolean) read(key, new Boolean(defaultValue));
        return (obj == null) ? defaultValue : obj.booleanValue();
    }

    /**
     * chtenie int polja Zebry iz nastroek prilozhenija
     */
    protected int read(String key, int defaultValue) {
        Integer obj = (Integer) read(key, new Integer(defaultValue));
        return (obj == null) ? defaultValue : obj.intValue();
    }

    /**
     * sokhranenie Object polja Zebry v nastrojkakh prilozhenija
     */
    protected void write(String key, Object value) {
        String serializedValue = serializeToString(value);
        // if (serializedValue != null)
        //   AbstractGUIClient.setPreference(PreferencesManager.getInstance().composeKey(EditorConstants.GENERIC_BASE, key), serializedValue);
    }

    /**
     * sokhranenie boolean polja Zebry v nastrojkakh prilozhenija
     */
    protected void write(String key, boolean value) {
        write(key, value);
    }

    /**
     * sokhranenie int polja Zebry v nastrojkakh prilozhenija
     */
    protected void write(String key, int value) {
        write(key, new Integer(value));
    }

    /**
     * poluchit' tekuschij sinkhronizirujuschij ob'ekt.
     */
    public static EditorOptions getCurrentEditorOptions() {
        if (m_currentZebraOptions == null) {
            m_currentZebraOptions = new EditorOptions();
            m_currentZebraOptions.restoreDefaults();
        }
        return m_currentZebraOptions;
    }


    /**
     * kloniruet dvumernyj massiv Object
     */
    protected static Object[][] cloneArray(Object[][] arr) {
        if (arr == null) return null;
        Object arr_1[][] = (Object[][]) Array.newInstance(((Object) (arr)).getClass().getComponentType(), new int[]{arr.length});
        for (int i = 0; i < arr.length; i++) {
            Object arr_2[] = (Object[]) Array.newInstance(((Object) (arr[i])).getClass().getComponentType(), arr[i].length);
            System.arraycopy(arr[i], 0, arr_2, 0, arr[i].length);
            arr_1[i] = arr_2;
        }

        return arr_1;
    }

    /**
     * kloniruet odnomernyj massiv Object
     */
    protected static Object[] cloneArray(Object[] arr) {
        if (arr == null) return null;
        Object arr_1[] = (Object[]) Array.newInstance(((Object) (arr)).getClass().getComponentType(), arr.length);
        System.arraycopy(arr, 0, arr_1, 0, arr.length);
        return arr_1;
    }


    /**
     * kloniruet odnomernyj massiv Object
     */
    protected static boolean[] cloneArray(boolean [] arr) {
        if (arr == null) return null;
        boolean arr_1[] = (boolean[]) Array.newInstance(arr.getClass().getComponentType(), arr.length);
        System.arraycopy(arr, 0, arr_1, 0, arr.length);
        return arr_1;
    }

    /**
     * kloniruet dvumernyj massiv boolean
     */
    protected static boolean[][] cloneArray(boolean[][] arr) {
        if (arr == null) return null;
        boolean arr_1[][] = new boolean[arr.length][];
        for (int i = 0; i < arr.length; i++) {
            boolean arr_2[] = new boolean[arr[i].length];
            System.arraycopy(arr[i], 0, arr_2, 0, arr[i].length);
            arr_1[i] = arr_2;
        }

        return arr_1;
    }


    /**
     * ustanavlivaet tekuschee polozhenie i razmer okna soobschenij
     */
    protected void setMessagesWndRect(Rectangle r) {
        if (r != null) {
            MESSAGES_WINDOW_RECT = r;
            write("MESSAGES_WINDOW_RECT"/*#Frozen*/, MESSAGES_WINDOW_RECT);
        }
    }

    /**
     * vozvraschaet tekuschee polozhenie i razmer okna soobschenij
     */
    protected Rectangle getMessagesWndRect() {
        return MESSAGES_WINDOW_RECT;
    }

    /**
     * ustanavlivaet tekuschee polozhenie i razmer okna soobschenij
     */
    protected void setIsMessagesAlwaysOnTop(boolean isAlwaysOnTop) {
        MESSAGES_ALWAYS_ON_TOP = isAlwaysOnTop;
        write("MESSAGES_ALWAYS_ON_TOP"/*#Frozen*/, MESSAGES_ALWAYS_ON_TOP);
    }

    /**
     * vozvraschaet tekuschee polozhenie i razmer okna soobschenij
     */
    protected boolean getIsMessagesAlwaysOnTop() {
        return MESSAGES_ALWAYS_ON_TOP;
    }


    public Font getZebraLineDefaultFont() {
        AttributeSet t_attr = EditorOptions.getCurrentEditorOptions().DEFAULT_TEXT_STYLE;

        int style = Font.PLAIN;
        if (StyleConstants.isBold(t_attr))
            style |= Font.BOLD;
        if (StyleConstants.isItalic(t_attr))
            style |= Font.ITALIC;
        return new Font(StyleConstants.getFontFamily(t_attr), style, StyleConstants.getFontSize(t_attr));
    }

    public int getZebraLineDefaultHeight() {
        Font f = getZebraLineDefaultFont();
        if (f == null)
            return 0;
        FontMetrics fm = Toolkit.getDefaultToolkit().getFontMetrics(f);
        return (fm == null) ? 0 : fm.getHeight();
    }
}
